﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Emgu.CV;
using MVSDK;//使用SDK接口
using CameraHandle = System.Int32;
using System.IO;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;
using Emgu.CV.Util;

namespace WinCoreV3Run
{
    //class MyCameral
    //{
    //    AsyncSaveImage asyncSaveImage=new AsyncSaveImage();
    //    private string[] getFilesFromPath()
    //    {
    //        string pathName = "";
    //        FolderBrowserDialog dialog = new FolderBrowserDialog();
    //        dialog.Description = "请选择一个文件夹";
    //        //是否显示对话框左下角 新建文件夹 按钮，默认为 true  
    //        dialog.ShowNewFolderButton = false;
    //        //按下确定选择的按钮  
    //        if (dialog.ShowDialog() == DialogResult.OK)
    //        {
    //            //记录选中的目录  
    //            pathName = dialog.SelectedPath;
    //        }
    //        string[] files = Directory.GetFiles(pathName, "*.*");
    //        return files;
    //    }
    //    public void OpenCameral()
    //    {
    //        if (asyncSaveImage.Initialize()==1)
    //        {
    //            string[] fileList = getFilesFromPath();

    //            for (int i = 0; i < fileList.Length; i++)
    //            {
    //                DateTime beforDT = System.DateTime.Now;
    //                Mat src = CvInvoke.Imread(fileList[i]);
    //                TestResult res =asyncSaveImage.TestImage(src);
    //                MoveBMP2Dir(fileList[i], res);
    //                DateTime afterDT = System.DateTime.Now;
    //                TimeSpan ts = afterDT.Subtract(beforDT);
    //                Console.WriteLine("------------------------DateTime总共花费{0}ms.", ts.TotalMilliseconds);

    //            }

    //        }

    //    }

    //    private void MoveBMP2Dir(string SrcPath, TestResult res)
    //    {


    //        switch (res.classIndex)
    //        {
    //            case 0:

    //                {

    //                    //空图
    //                    MyTools.MoveBMP2Dir(SrcPath, MyParam.nullPath);
    //                    break;
    //                }
    //            case 1:
    //                {
    //                    //有字
    //                    MyTools.MoveBMP2Dir(SrcPath, MyParam.allPath);
    //                    break;
    //                }


    //            case 2:
    //                {

    //                    MyTools.MoveBMP2Dir(SrcPath, MyParam.errPath);
    //                    break;

    //                }


    //            default:
    //                MessageBox.Show("errorrrrrrrrrrrrrr!!!");
    //                break;



    //        }

    //    }
    //}

    class MyCameral
    {

        private IntPtr m_Grabber = IntPtr.Zero;
        private CameraHandle m_hCamera = 0;
        private tSdkCameraDevInfo m_DevInfo;
        private pfnCameraGrabberFrameListener m_RawCallback;
        private AsyncSaveImage m_AsyncSave = new AsyncSaveImage();
        private int errTimes = 0;

        public int StartCamera(IntPtr wHnd)
        {
            m_AsyncSave.Initialize();
            CameraSdkStatus status = 0;
            m_RawCallback = new pfnCameraGrabberFrameListener(CameraGrabberRawCallback);
            tSdkCameraDevInfo[] DevList;
            MvApi.CameraEnumerateDevice(out DevList);
            int NumDev = (DevList != null ? DevList.Length : 0);
            if (NumDev < 1)
            {
                MessageBox.Show("未扫描到相机");

                return -2;
            }
            else if (NumDev == 1)
            {
                status = MvApi.CameraGrabber_Create(out m_Grabber, ref DevList[0]);
            }
            else
            {
                status = MvApi.CameraGrabber_CreateFromDevicePage(out m_Grabber);
            }

            if (status == 0)
            {
                MvApi.CameraGrabber_GetCameraDevInfo(m_Grabber, out m_DevInfo);
                MvApi.CameraGrabber_GetCameraHandle(m_Grabber, out m_hCamera);
                MvApi.CameraCreateSettingPage(m_hCamera, IntPtr.Zero, m_DevInfo.acFriendlyName, null, (IntPtr)0, 0);

                MvApi.CameraGrabber_SetFrameListener(m_Grabber, m_RawCallback, IntPtr.Zero);

                // 黑白相机设置ISP输出灰度图像
                // 彩色相机ISP默认会输出BGR24图像
                tSdkCameraCapbility cap;
                MvApi.CameraGetCapability(m_hCamera, out cap);
                if (cap.sIspCapacity.bMonoSensor != 0)
                {
                    MvApi.CameraSetIspOutFormat(m_hCamera, (uint)MVSDK.emImageFormat.CAMERA_MEDIA_TYPE_MONO8);
                }

                // 设置触发模式
                MvApi.CameraSetTriggerMode(m_hCamera, 0);
                MvApi.CameraSetTriggerCount(m_hCamera, 1);




                if (m_Grabber != IntPtr.Zero)
                    MvApi.CameraShowSettingPage(m_hCamera, 1);
                if (MyParam.showWindow == 1)
                    MvApi.CameraGrabber_SetHWnd(m_Grabber, wHnd);

                MvApi.CameraGrabber_StartLive(m_Grabber);
       
                return 0;
            }
            else
            {
                string kk = String.Format("打开相机失败，原因：{0}", status);
                MessageBox.Show(kk);
                return -1;

            }
        }

        private int CameraGrabberRawCallback(IntPtr Grabber, int Phase, IntPtr pFrameBuffer, ref tSdkFrameHead pFrameHead, IntPtr Context)
        {
            if (Phase == 0)
            {
                DateTime beforDT = System.DateTime.Now;
                IntPtr Image;
                if (MvApi.CameraImage_Create(out Image, pFrameBuffer, ref pFrameHead, 1) != CameraSdkStatus.CAMERA_STATUS_SUCCESS)
                    return 1;
                IntPtr pRaw, pHeadPtr;
                MvApi.CameraImage_GetData(Image, out pRaw, out pHeadPtr);
                tSdkFrameHead FrameHead = (tSdkFrameHead)Marshal.PtrToStructure(pHeadPtr, typeof(tSdkFrameHead));

                uint uIspOutFmt = 0;
                MvApi.CameraGetIspOutFormat(m_hCamera, ref uIspOutFmt);

                int w = FrameHead.iWidth, h = FrameHead.iHeight;
                if (FrameHead.iWidthZoomSw > 0 && FrameHead.iHeightZoomSw > 0)
                {
                    w = FrameHead.iWidthZoomSw;
                    h = FrameHead.iHeightZoomSw;
                }

                bool IspOutGray = (uIspOutFmt == (uint)MVSDK.emImageFormat.CAMERA_MEDIA_TYPE_MONO8);
                int RequireBufferSize = w * h * (IspOutGray ? 1 : 3);
                IntPtr pFrameBufferTest = MvApi.CameraAlignMalloc(RequireBufferSize, 16);
                if (pFrameBufferTest != IntPtr.Zero)
                {
                    CameraSdkStatus res=MvApi.CameraImageProcess(m_hCamera, pRaw, pFrameBufferTest, ref FrameHead);
                    if (res != CameraSdkStatus.CAMERA_STATUS_SUCCESS)
                        return 1;
                    ///////////////////////////////////////////
                    //MvApi.CameraDisplayRGB24(item.hCamera, pFrameBufferTest, ref FrameHead);

                    //MvApi.CameraSaveImage(item.hCamera, item.FileName, pFrameBuffer, ref FrameHead, item.FileType, item.Quality);
                    //////////////////////////////////////
                    res = MvApi.CameraFlipFrameBuffer(pFrameBufferTest, ref FrameHead, 1);
                    if (res != CameraSdkStatus.CAMERA_STATUS_SUCCESS)
                        return 1;

                    Mat src = new Mat(new Size(FrameHead.iWidth, FrameHead.iHeight),
                                     Emgu.CV.CvEnum.DepthType.Cv8U, 3,
                                    pFrameBufferTest, 0);

                    try
                    {
                        if (src == null || src.IsEmpty || src.Width < MyParam.cutWidth || src.Height < MyParam.cutHeight)
                        {

                            return 1;
                        }
                    }
                    catch (Exception er)
                    {
                        return 1;
                    }
                   



                    Mat testA = new Mat(src, new System.Drawing.Rectangle(MyParam.cutX, MyParam.cutY, MyParam.cutWidth, MyParam.cutHeight));



                    VectorOfMat channels = new VectorOfMat(); //定义channels存储split后的各通道图像
                    CvInvoke.Split(testA, channels); //调用Split函数，分离yccImage颜色通道
                                                       //CvInvoke.EqualizeHist(channels[0], channels[0]); //对Y通道进行直方图均衡化
                                                       //CvInvoke.EqualizeHist(channels[1], channels[1]); //对Y通道进行直方图均衡化
                                                       //CvInvoke.EqualizeHist(channels[2], channels[2]); //对Y通道进行直方图均衡化

                    CvInvoke.CLAHE(channels[0], 40, new Size(16, 16), channels[0]);
                    CvInvoke.CLAHE(channels[1], 40, new Size(16, 16), channels[1]);
                    CvInvoke.CLAHE(channels[2], 40, new Size(16, 16), channels[2]);



                    Mat test = new Mat();
                    CvInvoke.Merge(channels, test);







                    TestResult tesulte = m_AsyncSave.TestImage(test.Clone());

   
                    if (MyParam.showWindow == 1)
                    {
                        CvInvoke.Imshow("Mat", test);
                        CvInvoke.WaitKey(1);


                    }
                    SaveBMP(test, tesulte);
                    MvApi.CameraAlignFree(pFrameBufferTest);
                    DateTime afterDT = System.DateTime.Now;
                    TimeSpan ts = afterDT.Subtract(beforDT);
                    Console.WriteLine("------------------------DateTime总共花费{0}ms.", ts.TotalMilliseconds);

                }


            }

            return 1;
        }
        public void CloseCamera()
        {
            if (m_Grabber != IntPtr.Zero)
                MvApi.CameraGrabber_StopLive(m_Grabber);
            MvApi.CameraGrabber_Destroy(m_Grabber);
        }
        private void SaveBMP(Mat bigSrc, TestResult res)
        {   ////


            //VectorOfMat channels = new VectorOfMat(); //定义channels存储split后的各通道图像
            //CvInvoke.Split(bigSrcA, channels); //调用Split函数，分离yccImage颜色通道
            //                                   //CvInvoke.EqualizeHist(channels[0], channels[0]); //对Y通道进行直方图均衡化
            //                                   //CvInvoke.EqualizeHist(channels[1], channels[1]); //对Y通道进行直方图均衡化
            //                                   //CvInvoke.EqualizeHist(channels[2], channels[2]); //对Y通道进行直方图均衡化

            //CvInvoke.CLAHE(channels[0],40 ,new Size(16, 16), channels[0]);
            //CvInvoke.CLAHE(channels[1], 40, new Size(16, 16), channels[1]);
            //CvInvoke.CLAHE(channels[2], 40, new Size(16, 16), channels[2]);



            //Mat bigSrc = new Mat();
            //CvInvoke.Merge(channels, bigSrc);



            ////
            switch (res.classIndex)
            {
                case 0:

                    {

                        //空图
                        if (MyParam.saveNull == 1)
                        {
                            MyTools.WriteNullBmp(bigSrc);
                        }

                        break;
                    }
                case 1:
                    {
                        //有字

                        if (res.probility >= MyParam.probility)
                        {
                            if (MyParam.showWindow == 1)
                            {

                                System.Console.WriteLine("检测到有字照片，产生输出");
                            }

                            MyTools.WriteAllBmp(bigSrc);
                        }
                        else
                        {
                            if (MyParam.showWindow == 1)
                            {

                                System.Console.WriteLine("检测到有字照片，可信度不够");
                            }
                            if (MyParam.saveNull == 1)
                            {
                                MyTools.WriteAllBmp(bigSrc);
                            }
                        }

                        break;
                    }


                case 2:
                    {

                        //错字
                        if (res.probility >= MyParam.probility)
                        {
                            if (MyParam.showWindow == 1)
                            {

                                System.Console.WriteLine("检测到ERR照片，可信度达到");
                            }

                            errTimes++;
                            if (errTimes > MyParam.errTimes)
                            {

                                MyTools.WriteErrBmp(bigSrc);
                                System.Console.WriteLine("检测Err照片，产生输出");
                            }

                        }
                        else
                        {
                            if (MyParam.showWindow == 1)
                            {

                                System.Console.WriteLine("检测Err照片，可信度不够");

                            }
                            if (MyParam.saveNull == 1)
                            {
                                MyTools.WriteErrBmp(bigSrc);
                            }
                        }


                        break;

                    }






            }



        }

    }


}
